package com.cn.xiaonuo.common.utils;


import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import com.cn.xiaonuo.common.constant.AlipayConstant;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.zip.ZipEntry;

/**
 * 支付宝对账明细工具
 */
public class AlipayBillUtils {

    // 支付宝的账单下载URl
    public static String getBillDownloadUrl() {
        String billdate = LocalDate.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));//账单查询日期
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayConstant.APP_ID, AlipayConstant.APP_PRIVATE_KEY, "json", "GBK", AlipayConstant.ALIPAY_PUBLIC_KEY, "RSA2");//获得初始化的AlipayClient
        AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();//创建API对应的request类
        HashMap<String,String> map=new HashMap<String,String>();
        map.put("bill_type","trade");
        map.put("bill_date",billdate);
        request.setBizContent(JSON.toJSONString(map)); //设置业务参数
        AlipayDataDataserviceBillDownloadurlQueryResponse response = null;//通过alipayClient调用API，获得对应的response类
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        System.out.println(response.getBillDownloadUrl());
        return response.getBillDownloadUrl();
    }

    /***
     * 通过支付宝查询对账单接口返回的url,下载zip文件
     * @param alipay_url
     * @param down_url
     * @return
     */
    public  static boolean downLoadZip(String alipay_url, String down_url) {
        boolean down_success = false;
        URL url = null;
        HttpURLConnection httpUrlConnection = null;
        InputStream fis = null;
        FileOutputStream fos = null;
        try {
            url = new URL(alipay_url);
            httpUrlConnection = (HttpURLConnection) url.openConnection();
            httpUrlConnection.setConnectTimeout(5 * 1000);
            httpUrlConnection.setDoInput(true);
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setUseCaches(false);
            httpUrlConnection.setRequestMethod("GET");
            httpUrlConnection.setRequestProperty("Charsert", "UTF-8");
            httpUrlConnection.connect();
            fis = httpUrlConnection.getInputStream();
            byte[] temp = new byte[1024];
            int b;
            fos = new FileOutputStream(new File(down_url));
            while ((b = fis.read(temp)) != -1) {
                fos.write(temp, 0, b);
                fos.flush();
            }
            down_success = true;
            System.out.println("支付宝对账单文件下载成功.....");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(fis!=null) {
                    fis.close();
                }
                if(fos!=null) {
                    fos.close();
                }
                if(httpUrlConnection!=null) {
                    httpUrlConnection.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return down_success;
    }

    /**
     * 解压支付宝对账单zip
     * @param zipFPath 解压包地址
     * @param desPath  解压路径
     * @throws Exception
     */
    public static void unZip(String zipFPath, String desPath)
            throws Exception {

        ZipFile zipFile = new ZipFile(zipFPath, "GBK");
        Enumeration<?> emu = zipFile.getEntries();
        BufferedInputStream bis;
        FileOutputStream fos;
        BufferedOutputStream bos;
        File file, parentFile;
        ZipEntry entry;
        byte[] cache = new byte[1024];
        while (emu.hasMoreElements()) {
            entry = (ZipEntry) emu.nextElement();
            if (entry.isDirectory()) {
                new File(desPath + entry.getName()).mkdirs();
                continue;
            }
            bis = new BufferedInputStream(zipFile.getInputStream((ZipArchiveEntry) entry));
            file = new File(desPath + entry.getName());
            parentFile = file.getParentFile();
            if (parentFile != null && (!parentFile.exists())) {
                parentFile.mkdirs();
            }
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos, 1024);
            int nRead = 0;
            while ((nRead = bis.read(cache, 0, 1024)) != -1) {
                fos.write(cache, 0, nRead);
            }
            bos.flush();
            bos.close();
            fos.close();
            bis.close();
        }
        zipFile.close();
    }

}
